


#include "person.h"
#include "mutator.h"



// PeopleMutator ::



PeopleMutator::PeopleMutator( CollectionSubjects *subs, CollectionCategories *cats )
    : Mutator(subs, cats)
    , m_nNameStage(0)
    , m_nNameStages(1)
{
    // compute how many name mutation steps are needed (factorial)
    for( uint8_t i = 2; i <= m_pSubjects->size(); ++i )
        m_nNameStages *= i;
}



/// \return true if full mutation done
bool PeopleMutator::mutate()
{
    // here we use the fact, that we have at maximum 3 persons,
    // and all the permutations for 3 objects are achievable by swapping the objects in initial permutation only in 2 pairs - 1st and 2nd pairs of objects.
    // swapping the pairs like - 1, 2, 1, 2, 1 gives us all the 6 permutations of 3 objects: 123, 213, 231, 321, 312, 132
    // in case if the number of objects is bigger - the permutation code is much more complex
    
    if( Mutator::mutate() )
    {
        // mutate names
        if( ++m_nNameStage < m_nNameStages )
        {
            CollectionSubjects::iterator is = m_pSubjects->begin();
            // if the stage is even - swap the second pair
            if( m_nNameStage%2 == 0 )
                ++is;

            // get two persons and swap their names
            Person *person1 = static_cast<Person*>(*is);
            Person *person2 = static_cast<Person*>(*++is);
            const char *name_holder = person1->getName();
            person1->mutateName( person2->getName() );
            person2->mutateName( name_holder );
            return false;
        }
        return true;
    }
    return false;
}



void PeopleMutator::restore()
{
    m_nNameStage = 0;
    Mutator::restore();
}
